#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 此脚本用来提取密码字典中符合条件的密码
import csv
import hashlib
import time
from concurrent.futures import ThreadPoolExecutor

import bcrypt  # 版本4.1.1，高版本会报错

# 公司的密码导出文件包含id,md5密码,salt
file_path = 'C:/Users/yangjianzhang/Desktop/'
file_name = '测试'

# 创建不合规的密码存储文件，将不合规的密码放入该文件
pass_ok = open(file_path + file_name + '-不合规密码.txt', 'a+')


# 读取csv文件中的id,md5密码,salt盐
def read_csv_file(file_path):
    data = []
    try:
        with open(file_path, mode='r', newline='', encoding='utf-8') as file:
            reader = csv.reader(file)
            for row in reader:
                data.append(row)
    except FileNotFoundError:
        print(f"文件 {file_path} 未找到")
    except Exception as e:
        print(f"读取文件时出现错误: {e}")
    return data


# 实现md5方法
def calculate_md5(input_string):
    # 创建一个 MD5 对象
    md5 = hashlib.md5()
    # 更新 MD5 对象，传入要计算哈希的字节数据
    md5.update(input_string.encode('utf-8'))
    # 获取 MD5 哈希结果，以十六进制字符串表示
    md5_hex = md5.hexdigest()
    return md5_hex


# 验证密码
def password_verify(passwd, hashed):
    passwd = passwd.encode('utf-8')
    hashed = hashed.encode('utf-8')
    return bcrypt.checkpw(passwd, hashed)


# select distinct u.id,u.mobile,u.`password` from pc_user u where u.`password` is not null
def handle_pw(pwd, user_pwd):
    print(pwd + '-' + user_pwd[0])
    pwd = pwd
    password = user_pwd[2]
    flag = False
    try:
        flag = password_verify(pwd, password)
    except Exception as e:
        print(user_pwd[0] + "\t" + user_pwd[1] + '\t' + '异常:' + str(e))

    if flag:
        info = user_pwd[0] + "\t" + user_pwd[1] + '\t' + '使用了弱密码' + pwd + "\n"
        pass_ok.write(info)


if __name__ == '__main__':

    # 将密码放入内存
    csv_data = read_csv_file(file_path + file_name + '.csv')

    # 该文件存储所有的简单密码，例如123这种密码
    password = open(file_path + "简单密码库.txt", encoding='UTF-8')
    count = 0
    ok_count = 0
    passlist = []
    # 创建不合规的密码存储文件，将不合规的密码放入该文件
    # pass_ok = open(file_path + file_name + '-不合规密码.txt', 'a+')
    # 将所有简单密码放入内存
    for count, line in enumerate(password):
        pwd = line.strip("\n")
        # print(type(pwd))
        passlist.append(pwd)

    # 线程池
    executor = ThreadPoolExecutor(max_workers=12)

    # 用简单密码库中的密码去碰撞公司的用户密码，如果是简单密码，将用户id、密码存入不合规密码.txt文件
    for user_pwd in csv_data:
        begin = int(time.time())
        for pwd in passlist:
            # handle_pw(pwd, user_pwd)
            executor.submit(handle_pw, pwd, user_pwd)
        end = int(time.time())
        print('id:%s 耗时%d秒' % (user_pwd[0], (end - begin)))
    executor.shutdown()
    print('结束')
    # 释放
    pass_ok.close()
